/*
 * Copyright (c) 2014 laidian. All Rights Reserved.
 * @author jiangchao
 * @date  2019-04-22 10:07
 */
package com.yao.activiti.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;


//@Configuration
//@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    private static final String DISCOVERY_REALM = "Laidian Workflow Service realm";
    @Value("${spring.activiti.security.enabled:false}")
    private boolean security;
    @Value("${spring.activiti.security.user.name:ld-activiti}")
    private String activitiUser;
    @Value("${spring.activiti.security.user.password:123456}")
    private String activitiPassword;
    @Value("${spring.activiti.security.ssl:false}")
    private boolean verifySslCertificatesOfServices;
    private Logger logger = LoggerFactory.getLogger(SecurityConfiguration.class);

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().permitAll().and().logout().permitAll();
    }

   /* @Override
    protected void configure(HttpSecurity http) throws Exception {
        //禁用跨域
        http.csrf().disable();
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.headers().httpStrictTransportSecurity().disable();

        if (security) {
            //注意： http://${user}:${password}@${host}:${port}/eureka/ 这种方式登录,必须是httpBasic
            if (verifySslCertificatesOfServices) {
                http.antMatcher("/**").authorizeRequests().anyRequest().authenticated().and().x509()
                        .userDetailsService(x509UserDetailsService()).and().httpBasic();
            } else {
                //所有路径需要验证 /eureka/**"
                http.httpBasic().realmName(DISCOVERY_REALM).and().antMatcher("/**")
                        .authorizeRequests()
                        .anyRequest().authenticated();
            }
        }

    }*/

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        auth
                .inMemoryAuthentication().passwordEncoder(encoder)
                //eureka-security-client
                .withUser(activitiUser).password(encoder.encode(activitiPassword))
                .roles("ACTIVITI-CLIENT");
        ;
    }

    public UserDetailsService x509UserDetailsService() {
        return myUserDetailsService();
        /*return new UserDetailsService() {
            @Override
            public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
                List<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
                authorities.add(new SimpleGrantedAuthority("ACTIVITI-CLIENT"));
                return new User(activitiUser, activitiPassword, authorities);
            }
        };*/
    }

    @Bean
    public UserDetailsService myUserDetailsService() {
        InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();

        String[][] usersGroupsAndRoles = {
                {"admin", "password", "ROLE_ACTIVITI_ADMIN"},
                {"system", "password", "ROLE_ACTIVITI_USER"},
                {activitiUser, activitiPassword, "ROLE_ACTIVITI_USER"},
                {"156", "password", "ROLE_ACTIVITI_USER"},

        };

        for (String[] user : usersGroupsAndRoles) {
            List<String> authoritiesStrings = Arrays.asList(Arrays.copyOfRange(user, 2, user.length));
            logger.info("> Registering new user: " + user[0] + " with the following Authorities[" + authoritiesStrings + "]");
            inMemoryUserDetailsManager.createUser(new User(user[0], passwordEncoder().encode(user[1]),
                    authoritiesStrings.stream().map(s -> new SimpleGrantedAuthority(s)).collect(Collectors.toList())));
        }


        return inMemoryUserDetailsManager;
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

